#include "contactlist.h"
#include <QPainter>
#include <QScrollBar>
#include <QStyleOption>
#include <QStylePainter>
#include <QWheelEvent>
#include "contactlisttoolitem.h"
#include "frienditem.h"
#include "loadingdlg.h"
#include "tcpmgr.h"
#include "usermgr.h"
#include <memory>
ContactList::ContactList(QWidget *parent)
    : QListWidget(parent)
    , _loadPending(false)
{
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    verticalScrollBar()->setVisible(false);
    setObjectName("ContactList");
    setSelectionMode(QListWidget::NoSelection);
    init();
    // 加载一页联系人
    loadContact();
    // 收到对方同意添加好友请求
    connect(TcpMgr::GetInstance().get(),
            &TcpMgr::sig_addAuthFriend,
            this,
            &ContactList::slot_receiveFriendAuth);
    // 同意对方添加好友
    connect(TcpMgr::GetInstance().get(),
            &TcpMgr::sig_authRsp,
            this,
            &ContactList::slot_AgreeFriendApply);
    // 滚动滚轮加载好友
    this->viewport()->installEventFilter(this);
}

void ContactList::init()
{
    // 提示标签
    addTip("新的朋友");
    // 新的朋友项
    ContactListToolItem *toolItem = new ContactListToolItem(this,
                                                            ":/icon/icon/newFriend.png",
                                                            "新的朋友");

    // 显示小红点
    connect(this,
            &ContactList::sig_newFriendRedPointVisible,
            toolItem,
            &ContactListToolItem::slot_RedPointVisible);
    // 鼠标点击新的朋友项 显示好友申请列表
    connect(toolItem,
            &ContactListToolItem::sig_clicked,
            this,
            &ContactList::sig_showFriendApplyPage);

    QListWidgetItem *item = new QListWidgetItem(this);
    item->setSizeHint(toolItem->sizeHint());
    item->setFlags(Qt::NoItemFlags);
    addItem(item);
    setItemWidget(item, toolItem);
    // 联系人
    addTip("联系人");
}

void ContactList::addNewFriend(std::shared_ptr<FriendInfo> friendInfo)
{
    FriendItem *friendItem = new FriendItem(this);
    // 发送用户被点击信号
    connect(friendItem, &FriendItem::sig_friendClicked, this, &ContactList::sig_friendClicked);
    if (friendInfo->icon.trimmed().isEmpty()) {
        friendInfo->icon = GetRandomIcon();
    }
    friendItem->setFriendInfo(friendInfo);
    QListWidgetItem *item = new QListWidgetItem(this);
    item->setFlags(Qt::NoItemFlags);
    item->setSizeHint(friendItem->sizeHint());
    addItem(item);
    setItemWidget(item, friendItem);
}

void ContactList::addNewFriends(const QVector<std::shared_ptr<FriendInfo> > friendInfoList)
{
    foreach (auto &info, friendInfoList) {
        addNewFriend(info);
    }
}

void ContactList::loadContact()
{
    if (_loadPending == true)
        return;
    _loadPending = true;
    LoadingDlg *loadingDialog = new LoadingDlg(this);
    loadingDialog->show();
    // 加载联系人
    if (UserMgr::GetInstance()->IsLoadContactFinish()) {
        loadingDialog->deleteLater();
        _loadPending = false;
        return;
    }
    auto friendList = UserMgr::GetInstance()->GetContactListPerPage();
    UserMgr::GetInstance()->UpdateContactLoadedCount();
    if (!friendList.isEmpty()) {
        addNewFriends(friendList);
    }
    loadingDialog->deleteLater();
    _loadPending = false;
}

void ContactList::addTip(QString text)
{
    QLabel *lb = new QLabel(this);
    lb->setObjectName("ContactList_tip");
    lb->setText(text);
    lb->setDisabled(true);
    QListWidgetItem *item = new QListWidgetItem(this);
    item->setFlags(Qt::NoItemFlags);
    item->setSizeHint(lb->sizeHint());
    addItem(item);
    setItemWidget(item, lb);
}

void ContactList::slot_receiveFriendAuth(std::shared_ptr<AuthInfo> authInfo)
{
    if (!authInfo) {
        // 空指针
        qDebug() << "authInfo is null!\n";
        return;
    }
    int uid = authInfo->uid;
    if (UserMgr::GetInstance()->FriendExists(uid))
        return;
    std::shared_ptr<FriendInfo> friendInfo = std::make_shared<FriendInfo>();
    friendInfo->name = authInfo->name;
    friendInfo->uid = authInfo->uid;
    friendInfo->icon = authInfo->icon;
    friendInfo->remark = authInfo->remark;
    friendInfo->desc = authInfo->desc;

    addNewFriend(friendInfo);
    UserMgr::GetInstance()->AddFriend(friendInfo);
}

void ContactList::slot_AgreeFriendApply(std::shared_ptr<AuthRsp> authRsp)
{
    if (!authRsp) {
        // 空指针
        return;
    }
    int uid = authRsp->uid;
    if (UserMgr::GetInstance()->FriendExists(uid))
        return;
    std::shared_ptr<FriendInfo> friendInfo = std::make_shared<FriendInfo>();
    friendInfo->name = authRsp->name;
    friendInfo->uid = uid;
    friendInfo->icon = authRsp->icon;
    friendInfo->remark = authRsp->remark;
    friendInfo->desc = authRsp->desc;
    addNewFriend(friendInfo);
    UserMgr::GetInstance()->AddFriend(friendInfo);
}

void ContactList::paintEvent(QPaintEvent *event)
{
    QStylePainter painter(this->viewport());
    QStyleOption option;
    option.initFrom(this->viewport());
    painter.drawPrimitive(QStyle::PE_Widget, option);
    QListWidget::paintEvent(event);
}

void ContactList::wheelEvent(QWheelEvent *event)
{
    int numDegrees = event->angleDelta().y() / 8;
    int numSteps = numDegrees / 15;
    // 设置滚动幅度
    int curValue = verticalScrollBar()->value();
    verticalScrollBar()->setValue(curValue - numSteps);
    // 检查是否滚动到底部
    int maxScrollValue = verticalScrollBar()->maximum();
    int currentValue = verticalScrollBar()->value();
    if (maxScrollValue - currentValue <= 0) {
        loadContact();
    }
    QListWidget::wheelEvent(event);
}

bool ContactList::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == this->viewport()) {
        if (event->type() == QEvent::Enter) {
            verticalScrollBar()->setVisible(true);
            return true;
        }
        if (event->type() == QEvent::Leave) {
            verticalScrollBar()->setVisible(false);
            return true;
        }
    }
    return QListWidget::eventFilter(watched, event);
}
